from datetime import datetime, UTC
from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin

db = SQLAlchemy()

class User(UserMixin, db.Model):
    __table_args__ = {'extend_existing': True}
    id = db.Column(db.Integer, primary_key=True)
    student_id = db.Column(db.String(20), unique=True, nullable=False)
    username = db.Column(db.String(80), nullable=False)
    password_hash = db.Column(db.String(128))
    email = db.Column(db.String(120), unique=True)
    is_teacher = db.Column(db.Boolean, default=False)
    is_admin = db.Column(db.Boolean, default=False)
    created_at = db.Column(db.DateTime, default=datetime.now(UTC))
    avatar = db.Column(db.String(200), default='default.png')
    bio = db.Column(db.Text)
    last_seen = db.Column(db.DateTime, default=datetime.now(UTC))
    
    # 关系
    favorite_books = db.relationship('Book', secondary='user_favorites', backref='favorited_by')
    favorite_posts = db.relationship('Post', secondary='post_favorites', backref='favorited_by')
    notifications = db.relationship('Notification', back_populates='user', lazy='dynamic')
    uploaded_books = db.relationship('Book', backref='uploader', lazy='dynamic', 
                                  foreign_keys='Book.uploader_id')
    
    def set_password(self, password):
        from werkzeug.security import generate_password_hash
        self.password_hash = generate_password_hash(password)
        
    def check_password(self, password):
        from werkzeug.security import check_password_hash
        return check_password_hash(self.password_hash, password)

class Category(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    description = db.Column(db.Text)
    books = db.relationship('Book', backref='category', lazy=True)
    created_at = db.Column(db.DateTime, default=datetime.now(UTC))

class Book(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    author = db.Column(db.String(100))
    description = db.Column(db.Text)
    file_path = db.Column(db.String(200))
    cover_path = db.Column(db.String(200))
    uploader_id = db.Column(db.Integer, db.ForeignKey('user.id', name='fk_book_uploader'), nullable=False)
    category_id = db.Column(db.Integer, db.ForeignKey('category.id', name='fk_book_category'))
    created_at = db.Column(db.DateTime, default=datetime.now(UTC))
    views = db.Column(db.Integer, default=0)
    tags = db.Column(db.String(200))  # 存储标签，用逗号分隔 
    status = db.Column(db.String(20), default='pending')  # pending, approved, rejected
    comments = db.relationship('BookComment', backref='book', lazy='dynamic', cascade='all, delete-orphan')
    rating = db.Column(db.Float, default=0)  # 平均评分
    rating_count = db.Column(db.Integer, default=0)  # 评分数量

class BookComment(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.Text, nullable=False)
    rating = db.Column(db.Integer)  # 1-5星评分
    author_id = db.Column(db.Integer, db.ForeignKey('user.id', name='fk_book_comment_author'))
    book_id = db.Column(db.Integer, db.ForeignKey('book.id', name='fk_book_comment_book'))
    created_at = db.Column(db.DateTime, default=datetime.now(UTC))
    author = db.relationship('User', backref='book_comments')

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200), nullable=False)
    content = db.Column(db.Text, nullable=False)
    author_id = db.Column(db.Integer, db.ForeignKey('user.id', name='fk_post_author'))
    created_at = db.Column(db.DateTime, default=datetime.now(UTC))
    updated_at = db.Column(db.DateTime, default=datetime.now(UTC), onupdate=datetime.now(UTC))
    circle_id = db.Column(db.Integer, db.ForeignKey('circle.id', name='fk_post_circle'))
    status = db.Column(db.String(20), default='approved')  # pending, approved, rejected
    comments = db.relationship('Comment', backref='post', lazy='dynamic', cascade='all, delete-orphan')
    author = db.relationship('User', backref='posts')
    likes = db.Column(db.Integer, nullable=False, default=0)  # 点赞数
    favorites = db.Column(db.Integer, nullable=False, default=0)  # 收藏数

class Comment(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.Text, nullable=False)
    author_id = db.Column(db.Integer, db.ForeignKey('user.id', name='fk_comment_author'))
    post_id = db.Column(db.Integer, db.ForeignKey('post.id', name='fk_comment_post'))
    created_at = db.Column(db.DateTime, default=datetime.now(UTC))
    status = db.Column(db.String(20), default='approved')  # pending, approved, rejected
    author = db.relationship('User', backref='comments')

class Circle(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    description = db.Column(db.Text)
    teacher_id = db.Column(db.Integer, db.ForeignKey('user.id', name='fk_circle_teacher'))
    created_at = db.Column(db.DateTime, default=datetime.now(UTC))
    members = db.relationship('User', secondary='circle_members')
    posts = db.relationship('Post', backref='circle', lazy='dynamic')

class Notification(db.Model):
    __tablename__ = 'notifications'
    
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    content = db.Column(db.Text, nullable=False)
    type = db.Column(db.String(50), default='general')
    title = db.Column(db.String(255))
    related_id = db.Column(db.Integer)
    is_read = db.Column(db.Boolean, default=False)
    created_at = db.Column(db.DateTime, default=datetime.now(UTC))
    
    user = db.relationship('User', back_populates='notifications')

class ReadingProgress(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id', name='fk_reading_progress_user'))
    book_id = db.Column(db.Integer, db.ForeignKey('book.id', name='fk_reading_progress_book'))
    page = db.Column(db.Integer, default=1)  # 当前页数
    last_read = db.Column(db.DateTime, default=datetime.now(UTC))
    
    user = db.relationship('User', backref='reading_progress')
    book = db.relationship('Book', backref='reading_progress')

class Bookmark(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id', name='fk_bookmark_user'))
    book_id = db.Column(db.Integer, db.ForeignKey('book.id', name='fk_bookmark_book'))
    page = db.Column(db.Integer)
    note = db.Column(db.Text)
    created_at = db.Column(db.DateTime, default=datetime.now(UTC))
    
    user = db.relationship('User', backref='bookmarks')
    book = db.relationship('Book', backref='bookmarks')

class UserActivity(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id', name='fk_user_activity_user'))
    activity_type = db.Column(db.String(50))  # 例如：login, book_view, book_download, post_view
    timestamp = db.Column(db.DateTime, default=datetime.now(UTC))
    target_id = db.Column(db.Integer)  # 关联的对象ID（如书籍ID，帖子ID等）
    
    user = db.relationship('User', backref='activities')

# 关联表
circle_members = db.Table('circle_members',
    db.Column('circle_id', db.Integer, db.ForeignKey('circle.id', name='fk_circle_members_circle'), primary_key=True),
    db.Column('user_id', db.Integer, db.ForeignKey('user.id', name='fk_circle_members_user'), primary_key=True)
)

user_favorites = db.Table('user_favorites',
    db.Column('user_id', db.Integer, db.ForeignKey('user.id', name='fk_user_favorites_user'), primary_key=True),
    db.Column('book_id', db.Integer, db.ForeignKey('book.id', name='fk_user_favorites_book'), primary_key=True)
)

post_likes = db.Table('post_likes',
    db.Column('user_id', db.Integer, db.ForeignKey('user.id', name='fk_post_likes_user'), primary_key=True),
    db.Column('post_id', db.Integer, db.ForeignKey('post.id', name='fk_post_likes_post'), primary_key=True)
)

post_favorites = db.Table('post_favorites',
    db.Column('user_id', db.Integer, db.ForeignKey('user.id', name='fk_post_favorites_user'), primary_key=True),
    db.Column('post_id', db.Integer, db.ForeignKey('post.id', name='fk_post_favorites_post'), primary_key=True)
) 